﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace OnlineMealOrdering.Extends
{
    public class TempDataHelper
    {
        /// <summary>
        /// add object to  temp data with list
        /// </summary>
        /// <typeparam name="T">the type which will be saved</typeparam>
        /// <param name="tempData">controller's property for temp data</param>
        /// <param name="keyName">key for TempData to save data collection</param>
        /// <param name="obj">data which will be saved in TempData</param>
        public static void AddObjectToList<T>(TempDataDictionary tempData, string keyName, T obj)
        {
            if (!tempData.ContainsKey(keyName))
            {
                tempData.Add(keyName, new List<T>() { obj });
            }
            else
            {
                var list = (List<T>)tempData.SingleOrDefault(a => a.Key == keyName).Value;
                list.Add(obj);
            }

            tempData.Keep();
        }

        /// <summary>
        /// add object to temp data
        /// </summary>
        /// <typeparam name="T">the type which will be added</typeparam>
        /// <param name="tempData">controller's property to save temp data</param>
        /// <param name="keyName">key in tempdata</param>
        /// <param name="obj">object which will be added to tempdata</param>
        public static void AddObject<T>(TempDataDictionary tempData, string keyName, T obj)
        {
            tempData[keyName] = obj;
            tempData.Keep();
        }

        /// <summary>
        /// get one object from list which is associated with one key  in TempData 
        /// </summary>
        /// <typeparam name="T">data type</typeparam>
        /// <param name="tempData">TempData of controller</param>
        /// <param name="keyName">key for TempData to save data collection</param>
        /// <param name="selector">lamda expression for get data from data collection</param>
        /// <returns></returns>
        public static T GetObjectFromList<T>(TempDataDictionary tempData, string keyName, Func<T, bool> selector)
        {
            T ret = default(T);

            if (tempData.ContainsKey(keyName))
            {
                var list = (List<T>)tempData.SingleOrDefault(a => a.Key == keyName).Value;
                ret = list.SingleOrDefault(selector);
            }

            tempData.Keep();
            return ret;
        }

        /// <summary>
        /// update object in list which is associated with one key in tempdata
        /// </summary>
        /// <typeparam name="T">the type which is saved in tempdata</typeparam>
        /// <param name="tempData">controller's property to save temp data</param>
        /// <param name="keyName">key in tempdata</param>
        /// <param name="selector">delegate which is used to select item from list</param>
        /// <param name="obj">new object which want to be saved in tempdata</param>
        public static void UpdateObjectInList<T>(TempDataDictionary tempData, string keyName, Func<T, bool> selector, T obj)
        {
            if (tempData.ContainsKey(keyName))
            {
                var list = (List<T>)tempData.SingleOrDefault(a => a.Key == keyName).Value;
                var oldObj = list.SingleOrDefault(selector);
                list[list.IndexOf(oldObj)] = obj;
            }
            tempData.Keep();
        }

        /// <summary>
        /// updata object in tempdata
        /// </summary>
        /// <typeparam name="T">the type which is saved in tempdata</typeparam>
        /// <param name="tempData">controller's property to save tempdata</param>
        /// <param name="keyName">key in tempdata</param>
        /// <param name="obj">object which want to be saved in tempdata</param>
        public static void UpdateObject<T>(TempDataDictionary tempData, string keyName, T obj)
        {
            if (tempData.ContainsKey(keyName))
            {
                tempData[keyName] = obj;
            }
            tempData.Keep();
        }

        /// <summary>
        /// get all data from TempData
        /// </summary>
        /// <typeparam name="T">the type which is used in tempdata</typeparam>
        /// <param name="tempData">TempData of controller</param>
        /// <param name="keyName">key for TempData to save data collection</param>
        /// <returns></returns>
        public static List<T> GetAllObjectsFromList<T>(TempDataDictionary tempData, string keyName)
        {
            List<T> ret = new List<T>();

            if (tempData.ContainsKey(keyName))
            {
                ret = (List<T>)tempData.SingleOrDefault(a => a.Key == keyName).Value;
            }

            tempData.Keep();
            return ret;
        }

        /// <summary>
        /// get object from tempdata
        /// </summary>
        /// <typeparam name="T">the type which is used in tempdata</typeparam>
        /// <param name="tempData">the controller's property to save tempdata</param>
        /// <param name="keyName">key which is used in tempdata</param>
        /// <returns>the type which is used in tempdata</returns>
        public static T GetObject<T>(TempDataDictionary tempData, string keyName)
        {
            T ret = default(T);

            if (tempData.ContainsKey(keyName))
            {
                ret = (T)tempData[keyName];

            }

            tempData.Keep();
            return ret;
        }

        /// <summary>
        /// remove item from list which is associated with key in tempdata
        /// </summary>
        /// <typeparam name="T">the type which is used in tempdata</typeparam>
        /// <param name="tempData">the controller's property to save data in tempdata</param>
        /// <param name="keyName">key in tempdata</param>
        /// <param name="selector">delegate which is used to get item from list in tempdata</param>
        public static void RemoveItemFromList<T>(TempDataDictionary tempData, string keyName, Func<T, bool> selector)
        {
            if (tempData.ContainsKey(keyName))
            {
                var list = (List<T>)tempData.SingleOrDefault(a => a.Key == keyName).Value;
                var item = list.FirstOrDefault(selector);

                if (item != null)
                {
                    list.Remove(item);
                }
            }
            tempData.Keep();
        }

        /// <summary>
        /// delete data from TempData by key
        /// </summary>
        /// <param name="tempData">controller's property to save tempdata</param>
        /// <param name="keyName">key in tempdata</param>
        public static void RemoveObject(TempDataDictionary tempData, string keyName)
        {
            if (tempData.ContainsKey(keyName))
            {
                tempData.Remove(keyName);
            }

            tempData.Keep();
        }

        /// <summary>
        /// delete all data collection from TempData
        /// </summary>
        /// <param name="tempData">controller's property to save tempdata</param>
        public static void ClearAll(TempDataDictionary tempData)
        {
            tempData.Clear();
        }
    }
}